package com.ccteam.fluidmusic.ui.auth

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import androidx.work.*
import com.ccteam.fluidmusic.utils.Event
import com.ccteam.fluidmusic.utils.cancelIfActive
import com.ccteam.fluidmusic.utils.preference.SettingWorker
import com.ccteam.fluidmusic.view.bean.ErrorMessage
import com.ccteam.fluidmusic.view.bean.LoadMessage
import com.ccteam.model.Resource
import com.ccteam.model.user.UserLoginDTO
import com.ccteam.shared.core.UserCore
import com.ccteam.shared.domain.auth.LoginDataUseCase
import com.ccteam.shared.domain.auth.RSADataUseCase
import com.orhanobut.logger.Logger
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * @author Xiaoc
 * @since 2021/3/18
 */
@HiltViewModel
class LoginViewModel @Inject constructor(
    application: Application,
    private val rsaDataUseCase: RSADataUseCase,
    private val loginDataUseCase: LoginDataUseCase,
    private val userCore: UserCore,
    private val oneTimeWorkRequest: OneTimeWorkRequest,
    private val periodicWorkRequest: PeriodicWorkRequest
): AndroidViewModel(application) {


    private val _isLogin = MutableLiveData(false)
    val isLogin: LiveData<Boolean> get() = _isLogin

    private val _loadMessage = MutableLiveData<Event<LoadMessage>>()
    val loadMessage: LiveData<Event<LoadMessage>> get() = _loadMessage

    private var loginJob: Job? = null
    init {
        loginJob = viewModelScope.launch {
            userCore.isLogin.collectLatest {
                _isLogin.value = it
            }
        }
    }

    fun login(phone: String,password: String){
        if(phone.isEmpty() || password.isEmpty()){
            _loadMessage.value = Event(LoadMessage.Error(
                ErrorMessage(description = "账号或密码未输入")))
            return
        }
        _loadMessage.value = Event(LoadMessage.Loading)
        viewModelScope.launch {
            val rsaResult = rsaDataUseCase(password)
            if(rsaResult is Resource.Success){

                val result = loginDataUseCase(UserLoginDTO(null,phone,rsaResult.data))

                if(result is Resource.Success){
                    // 将信息存储在DataStore中并更新
                    result.data?.let {
                        Logger.d("登录成功:$result")
                        _loadMessage.value = Event(LoadMessage.NotLoading)
                        userCore.login(it.userId,it.tokenValue)
                        // 获取一次云端设置信息
                        WorkManager.getInstance(getApplication()).enqueueUniqueWork(
                            SettingWorker.SETTING_WORKER_ONCE_TAG,
                            ExistingWorkPolicy.REPLACE,oneTimeWorkRequest
                        )
                        // 开启一个更新设置内容的定期任务
                        WorkManager.getInstance(getApplication()).enqueueUniquePeriodicWork(
                            SettingWorker.SETTING_WORKER_TAG,
                            ExistingPeriodicWorkPolicy.KEEP,periodicWorkRequest
                        )
                    }
                } else {
                    _loadMessage.value = Event(LoadMessage.Error(
                        ErrorMessage(result.message,result.errorCode)))
                }
            } else {
                _loadMessage.value = Event(LoadMessage.Error(
                    ErrorMessage(rsaResult.message,rsaResult.errorCode)))
                Logger.d("密钥获取失败:$rsaResult")
            }



        }
    }

    override fun onCleared() {
        super.onCleared()

        loginJob.cancelIfActive()
    }
}